{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Hands-on!\n",
    "\n",
    "Nessa prática, sugerimos alguns pequenos exemplos para você implementar sobre o Spark."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Estimar o Pi\n",
    "\n",
    "Existe um algoritmo para estimar o Pi com números radômicos. Implemente-o sobre o Spark.\n",
    "\n",
    "Descrição do algoritmo: http://www.eveandersson.com/pi/monte-carlo-circle\n",
    "\n",
    "Implementação EM PYTHON (__não sobre o SPARK__): http://www.stealthcopter.com/blog/2009/09/python-calculating-pi-using-random-numbers/\n",
    "\n",
    "O númer de pontos deve ser 100000 (cem mill) vezes o número mínimo de partições padrão do seu SparkContext (`sc.defaultMinPartitions`). Esses pontos devem ser selecionados aleatóriamente na etapa de map (ver observações).\n",
    "\n",
    "Observações: use as funções __map__ (para mapear as ocorrêncas em `0` ou `1`, significando `1` quando o ponto aleatório cair dentro do círculo e `0` quando o contrário) e __reduce__ (para sumar as ocorrências)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "from math import sqrt\n",
    "from random import *"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "def area(x,y):return 1 if sqrt(x*x+y*y)<=1 else  0\n",
    "\n",
    "def mapf(z):\n",
    "    x= random()\n",
    "    y=random()\n",
    "    return area(x, y)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "n = sc.defaultMinPartitions * 100000\n",
    "data = sc.parallelize(range(1, n))\n",
    "\n",
    "r = data.map(mapf)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "157336\n",
      "199999\n"
     ]
    }
   ],
   "source": [
    "soma = r.reduce(lambda a, b: a+b)\n",
    "print(soma)\n",
    "print(r.count())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "soma = int(soma)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "3.1467357336786685\n"
     ]
    }
   ],
   "source": [
    "pi = 4*(soma/(r.count()))\n",
    "print(pi)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Filtragem de Primos\n",
    "\n",
    "Dado uma sequência de números de `1` a `1000000`, filtre somente os primos dessa sequência."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "def isPrime(number):\n",
    "    for i in range(1,number):\n",
    "        if((i != 1) and (i != number)):\n",
    "            if ((number % i) == 0):\n",
    "                return False\n",
    "    print(number)\n",
    "    return True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[1, 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, 521, 523]\n"
     ]
    }
   ],
   "source": [
    "data = sc.parallelize(range(1, 1000000))\n",
    "\n",
    "r = data.filter(isPrime)\n",
    "\n",
    "print(r.take(100))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Municípios do Brasil\n",
    "\n",
    "Dado o dataset `mucipios_do_Brasil.csv`, faça duas operações com ele:\n",
    "\n",
    "1. Monte uma lista dos municípios por estado.\n",
    "2. Conte quantos municípios há em cada estado.\n",
    "\n",
    "Dicas: use as operações groupByKey e reduceByKey, não faça um count na lista da operação 1. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "file = sc.textFile('municipios_do_Brasil.csv')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "file_mapping = file.map(lambda line: line.split(',')).map(lambda word: (word[0], word[1]))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[('AC', 22), ('AP', 16), ('BA', 417), ('CE', 184), ('DF', 1), ('ES', 78), ('MG', 853), ('PE', 185), ('PR', 399), ('RJ', 92), ('RN', 167), ('SC', 293), ('SP', 645), ('TO', 137), ('uf', 1), ('AL', 102), ('AM', 62), ('GO', 246), ('MA', 217), ('MS', 78), ('MT', 141), ('PA', 143), ('PB', 223), ('PI', 224), ('RO', 67), ('RS', 496), ('SE', 75)]\n"
     ]
    }
   ],
   "source": [
    "#Contando o numero de municipios por Estado\n",
    "count_cities = file_mapping.map(lambda word: (word[0], 1)).reduceByKey(lambda x, y: x + y)\n",
    "\n",
    "print(count_cities.collect())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[('AC', ['Acrelândia', 'Assis Brasil', 'Brasiléia', 'Bujari', 'Capixaba', 'Cruzeiro do Sul', 'Epitaciolândia', 'Feijó', 'Jordão', 'Mâncio Lima', 'Manoel Urbano', 'Marechal Thaumaturgo', 'Plácido de Castro', 'Porto Acre', 'Porto Walter', 'Rio Branco', 'Rodrigues Alves', 'Santa Rosa do Purus', 'Sena Madureira', 'Senador Guiomard', 'Tarauacá', 'Xapuri'])]\n"
     ]
    }
   ],
   "source": [
    "#Listando os municipios por Estado\n",
    "list_cities = file_mapping.groupByKey().map(lambda x : (x[0], list(x[1])))\n",
    "\n",
    "print(list_cities.take(1))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": true
   },
   "source": [
    "## Word Count Memória Postumas de Brás Cubas\n",
    "\n",
    "Memórias Póstumas de Brás Cubas é um romance escrito por Machado de Assis, desenvolvido em princípio como folhetim, de março a dezembro de 1880, na Revista Brasileira, para, no ano seguinte, ser publicado como livro, pela então Tipografia Nacional.\n",
    "\n",
    "A obra retrata a escravidão, as classes sociais, o cientificismo e o positivismo da época. Dada essas informações, será que conseguimos idenficar essas características pelas palavras mais utilizadas em sua obra?\n",
    "\n",
    "Utilizando o dataset `Machado-de-Assis-Memorias-Postumas.txt`, faça um word count e encontre as palavras mais utilizadas por Machado de Assis em sua obra. Não esqueça de utilizar `stopwords.pt` para remover as `stop words`!"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "file2 = sc.textFile('Machado-de-Assis-Memorias-Postumas.txt')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "metadata": {},
   "outputs": [],
   "source": [
    "stopwords = sc.textFile('stopwords.pt')\n",
    "stopwords = stopwords.flatMap(lambda word: word.split())\n",
    "stopwords = stopwords.collect()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['(', ')', '?', '!', '\"', ';', '|', '[', ']', '.', ',', \"'\", '-', '+', '-', '*', '{', '}', '&', '%', '$', '#', '@', ':', '/', 'a', 'à', 'acordo', 'afirma', 'afirmou', 'agora', 'ainda', 'além', 'alguns', 'ano', 'anos', 'antes', 'ao', 'aos', 'apenas', 'após', 'aqui', 'área', 'as', 'às', 'assim', 'até', 'aumento', 'banco', 'bem', 'bilhões', 'bom', 'brasil', 'brasileira', 'brasileiro', 'brasília', 'cada', 'câmara', 'campanha', 'candidato', 'carlos', 'casa', 'caso', 'central', 'centro', 'cerca', 'cidade', 'cinco', 'cinema', 'coisa', 'com', 'como', 'congresso', 'conta', 'contra', 'da', 'dar', 'das', 'de', 'depois', 'deputado', 'desde', 'deve', 'dia', 'dias', 'dinheiro', 'direito', 'diretor', 'disse', 'diz', 'do', 'dois', 'dos', 'duas', 'durante', 'e', 'é', 'economia', 'econômica', 'ela', 'ele', 'eles', 'em', 'empresa', 'empresas', 'enquanto', 'então', 'entre', 'equipe', 'era', 'especial', 'essa', 'esse', 'esta', 'está', 'estado', 'estados', 'estão', 'estava', 'este', 'eu', 'eua', 'exemplo', 'falta', 'fato', 'faz', 'fazer', 'federal', 'fernando', 'fez', 'fhc', 'ficou', 'filho', 'filme', 'fim', 'final', 'foi', 'folha', 'fora', 'foram', 'forma', 'governo', 'grande', 'grupo', 'há', 'havia', 'henrique', 'história', 'hoje', 'inflação', 'início', 'isso', 'já', 'janeiro', 'jogo', 'josé', 'juros', 'justiça', 'lado', 'lei', 'livro', 'local', 'lugar', 'maior', 'mais', 'mas', 'me', 'média', 'meio', 'melhor', 'menos', 'mercado', 'mês', 'meses', 'mesma', 'mesmo', 'meu', 'mil', 'milhões', 'minha', 'ministério', 'ministro', 'momento', 'muito', 'mulher', 'mundo', 'na', 'nacional', 'nada', 'não', 'nas', 'nem', 'nesta', 'neste', 'no', 'noite', 'nome', 'nos', 'nós', 'nova', 'novo', 'num', 'numa', 'número', 'o', 'onde', 'ontem', 'os', 'ou', 'outra', 'outras', 'outro', 'outros', 'país', 'países', 'para', 'parte', 'partido', 'partir', 'passado', 'paulo', 'pela', 'pelo', 'pelos', 'período', 'pesquisa', 'pessoas', 'plano', 'pode', 'podem', 'poder', 'polícia', 'política', 'pontos', 'por', 'porém', 'porque', 'pouco', 'prazo', 'preço', 'preços', 'presidente', 'primeira', 'primeiro', 'problema', 'problemas', 'processo', 'produção', 'produtos', 'programa', 'projeto', 'próprio', 'pt', 'público', 'qual', 'qualquer', 'quando', 'quanto', 'quase', 'quatro', 'que', 'quem', 'quer', 'r', 'real', 'recursos', 'região', 'relação', 'reportagem', 'rio', 'são', 'saúde', 'se', 'segundo', 'seja', 'sem', 'semana', 'sempre', 'sendo', 'ser', 'será', 'serão', 'seria', 'setor', 'seu', 'seus', 'sido', 'silva', 'sistema', 'só', 'sobre', 'social', 'sociedade', 'sp', 'sua', 'suas', 'sucursal', 'sul', 'também', 'tão', 'tel', 'tem', 'têm', 'tempo', 'ter', 'teve', 'tinha', 'toda', 'todas', 'todo', 'todos', 'trabalho', 'três', 'tudo', 'último', 'um', 'uma', 'us', 'vai', 'valor', 'vão', 'vem', 'vez', 'vezes', 'vida', 'você', 'zona']"
      ]
     },
     "execution_count": 42,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "stopwords"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 54,
   "metadata": {},
   "outputs": [],
   "source": [
    "def filter_words(word):\n",
    "    print(word[0])\n",
    "    if word[0] in stopwords:\n",
    "        return False\n",
    "    return True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 59,
   "metadata": {},
   "outputs": [],
   "source": [
    "counts = file2.flatMap(lambda line: line.split(\" \")).map(lambda word: word.lower()).map(lambda word: (word, 1)).reduceByKey(lambda a, b: a + b)\n",
    "counts = counts.filter(filter_words)\n",
    "counts = counts.takeOrdered(100, key = lambda x: -x[1])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 60,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[('—', 723), ('', 303), ('capítulo', 174), ('lhe', 159), ('virgília', 111), ('olhos', 102), ('d.', 85), ('alguma', 81), ('talvez', 74), ('que,', 68), ('ia', 68), ('homem', 65), ('quincas', 65), ('podia', 60), ('fui', 58), ('dizer', 57), ('e,', 55), ('sei', 54), ('lá', 54), ('eram', 54), ('lobo', 52), ('logo', 50), ('algum', 49), ('isto', 49), ('meus', 48), ('dizia', 48), ('nossa', 46), ('idéia', 46), ('olhar', 45), ('mim', 45), ('eu,', 44), ('tal', 41), ('coisas', 41), ('fosse', 41), ('virgília,', 41), ('certo', 40), ('mão', 40), ('depois,', 38), ('modo', 38), ('nada.', 37), ('te', 37), ('simples', 37), ('tempo,', 36), ('uns', 35), ('ver', 35), ('pai', 35), ('creio', 35), ('aí', 34), ('não,', 33), ('ir', 33), ('sim,', 33), ('brás', 33), ('algumas', 33), ('nunca', 33), ('si', 32), ('marcela', 32), ('mim,', 31), ('digo', 30), ('ele,', 30), ('certa', 30), ('morte', 29), ('nenhum', 29), ('pé', 29), ('mas,', 29), ('tu', 29), ('anos,', 28), ('nosso', 28), ('muitas', 28), ('borba', 28), ('disse-me', 28), ('plácida', 28), ('casa,', 28), ('veio', 27), ('filha', 27), ('pois', 27), ('daí', 27), ('pai,', 26), ('ali', 26), ('boa', 26), ('porém,', 26), ('gesto', 26), ('muita', 26), ('verdade,', 25), ('devia', 25), ('fiquei', 25), ('leitor', 25), ('muito,', 25), ('porta', 25), ('homem,', 25), ('senão', 25), ('vinha', 25), ('fazia', 25), ('coisa,', 25), ('entrou', 24), ('assim,', 24), ('nada,', 24), ('outro,', 24), ('eu.', 24), ('mãe', 24), ('carta', 23)]\n"
     ]
    }
   ],
   "source": [
    "print(counts)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Apache Toree - PySpark",
   "language": "python",
   "name": "apache_toree_pyspark"
  },
  "language_info": {
   "codemirror_mode": "text/x-ipython",
   "file_extension": ".py",
   "mimetype": "text/x-ipython",
   "name": "python",
   "pygments_lexer": "python",
   "version": "3.6.2\n"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
